﻿using RiderShop.Web.YinxinPay.ChannelPayService;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace RiderShop.Web.YinxinPay
{
    public class YinxinPayHelper
    {
        private static string key;
        private static string channel;
        static YinxinPayHelper()
        {
            key = ConfigurationManager.AppSettings["YinxinPayKey"];
            channel = ConfigurationManager.AppSettings["YinxinPayChannel"];
        }

        public static string CreateGatewayOrderNumber(string order)
        {
            var gatewayOrder = channel
                    + ("0000000000").Substring(0, 16 - order.Length)
                    + order
                    + DateTime.Now.ToString("yyMMddHHmmss");
            return gatewayOrder;
        }

        //加密的Key
        public static string CommitOrder(string order, string card, string password, decimal money)
        {
            string formatMoney = money.ToString("###0.00");
            string time = FormateTime();
            string iv = time.Substring(time.Length - 8, 8);

            var pwdCode = CryptoString(password, iv);

            //需要加密的字符串
            string value = channel + order + card + pwdCode + formatMoney + time;

            string hash = CryptoString(value, iv);

            ChannelPayServiceClient client = new ChannelPayServiceClient();
            var result = client.commitOrder(channel, order, card, pwdCode, formatMoney, time, hash);
            return ErrorCodeMessage(result);
        }

        public static string QueryOrder(string order)
        {
            string time = FormateTime();
            string iv = time.Substring(time.Length - 8, 8);

            //需要加密的字符串
            string value = channel + order + time;

            string hash = CryptoString(value, iv);

            ChannelPayServiceClient client = new ChannelPayServiceClient();
            var result = client.queryOrder(channel, order, time, hash);
            return ErrorCodeMessage(result);
        }

        public static string QueryBalance(string card, string password)
        {
            string time = FormateTime();
            string iv = time.Substring(time.Length - 8, 8);

            var pwdCode = CryptoString(password, iv);

            //需要加密的字符串
            string value = channel + card + pwdCode + time;

            string hash = CryptoString(value, iv);

            ChannelPayServiceClient client = new ChannelPayServiceClient();
            var result = client.queryBalance(channel, card, pwdCode, time, hash);

            if (result.StartsWith("$200$"))
            {
                return "￥" + result.Replace("$200$", "");
            }

            return ErrorCodeMessage(result);
        }


        private static string CryptoString(string value, string iv)
        {
            ICryptoTransform ct;
            SymmetricAlgorithm des = new TripleDESCryptoServiceProvider();
            des.Key = Convert.FromBase64String(key);
            des.IV = Encoding.UTF8.GetBytes(iv);
            des.Mode = CipherMode.CBC;  //CBS
            des.Padding = PaddingMode.PKCS7;    //PKCS7Padding
            ct = des.CreateEncryptor(des.Key, des.IV);

            byte[] bt = Encoding.UTF8.GetBytes(value);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(bt, 0, bt.Length);
            cs.FlushFinalBlock();
            cs.Close();

            string hash = Convert.ToBase64String(ms.ToArray());
            return hash;
        }

        private static string FormateTime()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        public static string ErrorCodeMessage(string errCode)
        {
            switch (errCode.Remove(0, 1))
            {
                case "101": return "卡号或密码错误，请核对后重新输入。";// "找不到对应的卡号";
                case "102": return "服务异常，请稍后再试。";//"系统内部错误，发生此错误可以重试，如果还错误，表示系统异常。";
                case "200": return string.Empty;//"消费/退款成功";
                case "201": return "卡号或密码错误，请核对后重新输入。";//"消费/退款失败";
                case "202": return "正在处理订单";
                //case "204": return "重复订单（如果出错此错误，请查询订单状态，如果消费成功，不再消费，忽略此错误。如果消费失败，请生成新订单，再消费，如果是正在处理订单，请等待后再查询消费结果）";
                //case "205": return "没有找到要查询或撤销的订单";
                case "207": return "余额不足";
                //case "901": return "错误的channel号";
                //case "902": return "错误的时间戳";
                //case "903": return "hash校验错误";
                case "904": return "卡号密码错误。";//"参数错误（表示除channel,time,hash之外的参数错误）";
                default: return "系统错误，请稍后重试。";
            }
        }
    }
}
